﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nage.Algorithms;
using Nage.Algorithms.Population;
using Nage.Examples.Rastrigin;
using Utils.Logger;
using System.Threading;
using System.Globalization;
using Nage.Algorithms.Solution;
using Nage.Examples.Rastrigin.Solution;

namespace Nage.Examples.Rastrigin
{
    class Program
    {
        private static RastriginProblem problem;

        static void Main(string[] args)
        {
            if (args.Length != 5)
            {
                Console.WriteLine("Usage:\nProgram populationSize mutationRate delta crossoverRate stepCount");
                Console.Read();
                return;
            }

            SetCulture();
            try
            {
                int populationSize = Convert.ToInt32(args[0]);
                double mutationRate = Convert.ToDouble(args[1]);
                double delta = Convert.ToDouble(args[2]);
                double crossoverRate = Convert.ToDouble(args[3]);
                int stepCount = Convert.ToInt32(args[4]);

                problem = new RastriginProblem(populationSize, mutationRate, delta, crossoverRate, stepCount);
                problem.StepCompleted += RastriginProblemStepCompleted;
                PrintBestFit(problem.Solve());
            }
            catch (Exception ex)
            {
                Console.WriteLine("An unknown error occurred! Please see log files for details.");
                CLogger.LogError("Unexpected error!", ex);
            }

            Console.Read();
        }

        #region PrintBestFit
        static void PrintBestFit(IPopulation<Coordinates> finalPopulation)
        {
            Coordinates bestFit = finalPopulation.OrderBy(x => x.Fitness).FirstOrDefault();
            Console.WriteLine("===============================================");
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Best fit: {0}", bestFit);
            Console.ResetColor();
        } 
        #endregion

        #region RastriginProblemStepCompleted
        static void RastriginProblemStepCompleted(IPopulation<Coordinates> currentPopulation)
        {
            Console.WriteLine("===============================================");
            Console.WriteLine(currentPopulation);
        } 
        #endregion

        #region SetCulture
        static void SetCulture()
        {
            var culture = new CultureInfo("en-US");
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        } 
        #endregion
    }
}
